/*
 * Copyright (C) 2024 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an 'AS IS' BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef IMAGE_KNIFE_C_IMAGEKNIFE_DATA_H
#define IMAGE_KNIFE_C_IMAGEKNIFE_DATA_H

#include <string>
#include <multimedia/image_framework/image/pixelmap_native.h>
#include "imageknife_type.h"

namespace ImageKnifePro {
/**
 * @brief 联合类型基类, 不要直接构造该基类，使用派生类ImageSource
 */
struct OptionData {
public:
    /**
     * @brief 以字符串类型获取数据
     * @param result 字符串引用，写回获取的数据
     * @return 返回true表示操作成功，false表示类型错误
     */
    bool GetString(std::string &result) const;
    /**
     * @brief 以整型数获取数据
     * @param result 为int类型引用，写回获取的数据
     * @return 返回true表示操作成功，false表示类型错误
     */
    bool GetNumber(int &result) const;
    /**
     * @brief 以pixelmap类型获取数据，不能释放获取的pixelmap对象，由该类析构时自动释放
     * @param result 为OH_PixelmapNative 指针引用，写回获取的pixelmap对象地址
     * @return 返回true表示操作成功，false表示类型错误
     */
    bool GetPixelMap(OH_PixelmapNative *&result) const;
    /**
     * @brief 以pixelmap类型获取数据，并移交pixelmap对象管理权，不再析构时自动释放而是由调用者release pixelmap
     * @param result 为OH_PixelmapNative 指针引用，写回获取的pixelmap对象地址
     * @return 返回true表示操作成功，并将类型设成undefined。false表示类型错误
     */
    bool MovePixelMap(OH_PixelmapNative *&result);
    /**
     * @brief 以Resource类型获取数据
     * @param result 为Resource类型引用，写回获取的Resource数据
     * @return 返回true表示操作成功，false表示类型错误
     */
    bool GetResource(Resource &result) const;
    /**
     * @brief 设置联合类型的数据为字符串，会将之前的内部数据析构
     * @param str 要设置的字符串
     */
    void SetString(std::string str);
    /**
     * @brief 设置联合类型的数据为整型数，会将之前的内部数据析构
     * @param number 要设置的int整型
     */
    void SetNumber(int number);
    /**
     * @brief 设置联合类型的数据为pixelmmap对象指针，会将之前的内部数据析构
     * 设置成功后不要再去析构原来的pixelmap对象，会造成重复析构
     * @param pixelMap 要设置的OH_PixelmapNative对象指针
     */
    void SetPixelMap(OH_PixelmapNative *pixelMap);
    /**
     * @brief 设置联合类型的数据为resource，会将之前的内部数据析构
     * @param resource 要设置的resource
     */
    void SetResource(Resource resource);
    /**
     * @brief 判断实际的数据类型是否为DataType::Undefined
     * @return 返回true表示Undefined类型，false表示其它类型
     */
    bool IsUndefined();
    /**
     * @brief 将内部的数据清空，类型设置为DataType::Undefined
     */
    void SetUndefined();
    /**
     * 将内部数据相关信息以字符串返回
     * @return 返回的数据相关信息字符串
     */
    std::string ToString() const;
    /**
     * 获取内部数据的实际类型
     * @return 返回DataType::类型枚举
     */
    DataType GetType() const;

    OptionData();
    explicit OptionData(unsigned int type);
    ~OptionData();
private:
    union ImageSrc {
        std::string str;
        int number;
        OH_PixelmapNative *pixelMap;
        Resource resource;

        ImageSrc();
        ~ImageSrc();
    };

    unsigned int availableType_;
    DataType type_;
    ImageSrc data_;

    void CleanData();
};

/**
 * @brief 图片数据源对象，图片来源可以是网络url，本地文件路径，本地资源等
 * 限定联合类型范围： string, pixelmap, resource
 */
struct ImageSource : public OptionData {
    /**
     * @brief 构造空的图片源，其类型是UNDEFINED
     */
    ImageSource();
    /**
     * @brief 使用网络图片url，本地资源图片路径构造图片源
     * @param url 图片源字符串
     */
    explicit ImageSource(std::string url);
    /**
     * @brief 使用网络图片url(常量字符串)，本地资源图片路径构造图片源
     * @param url 图片源常量字符串
     */
    explicit ImageSource(const char* url);
    /**
     * @brief 使用pixelmap构造图片源
     * 构造后OH_PixelmapNative由该图片源释放，除非使用MovePixelMap取出图片源并移交管理权
     * @param pixelMap C侧OH_PixelmapNative对象指针
     */
    explicit ImageSource(OH_PixelmapNative *pixelMap);
    /**
     * @brief 使用Resource本地资源来构造图片源
     * @param resource 本地资源的映射对象，解析自ArkTs
     */
    explicit ImageSource(Resource resource);
};

} // end of namespace
#endif // IMAGE_KNIFE_C_IMAGEKNIFE_DATA_H
